/*
 * @Description: 资源(菜单，权限) Service
 * @Author: mengtao
 * @Date: 2021-12-17 09:46:49
 * @LastEditTime: 2022-01-11 09:32:41
 */
'use strict';

const Service = require('egg').Service;
const { v4: uuidv4 } = require('uuid');
const { Op } = require('sequelize');

class ResourcesService extends Service {

  /**
     * @description: 资源添加接口
     * @param {*} payload
     * @return {*}
     */
  async add(payload) {
    const { ctx } = this;
    const uuid = uuidv4();
    const data = { ...payload, id: uuid };
    await ctx.model.TResources.create(data);
    return ctx.helper.body.SUCCESS({ ctx, msg: '添加成功', data: null });
  }

  /**
   * @description: 资源修改接口
   * @param {*} payload
   * @return {*}
   */
  async update(payload) {
    const { ctx } = this;
    await ctx.model.TResources.update({ ...payload }, { where: { id: payload.id } });
    return ctx.helper.body.SUCCESS({ ctx, msg: '修改成功', data: null });
  }

  /**
   * @description: 资源删除接口
   * @param {*} payload
   * @return {*}
   */
  async destroy(payload) {
    const { ctx } = this;
    const rsp = await ctx.model.TResources.findOne({
      attributes: [ 'name' ],
      where: { parent_id: payload.id },
    });
    if (rsp) {
      return ctx.helper.body.ERROR({ ctx, msg: '已绑定下属资源，无法删除' });
    }
    await ctx.model.TResources.destroy({ where: { id: payload.id } });
    return ctx.helper.body.SUCCESS({ ctx, msg: '删除成功', data: null });
  }


  /**
   * @description: 获取所有资源
   * @param {*} payload
   * @return {*}
   */
  async getAllResources(payload) {
    const { ctx } = this;
    const { status, name_cn, type } = payload;
    let type_ = 2;
    const where = {};
    if (name_cn && name_cn.trim() !== '') {
      where.name_cn = { [Op.like]: `%${name_cn}%` };
    }
    if (status === 0 || status) {
      where.status = { [Op.eq]: status };
    }
    if (type) {
      type_ = type;
    }
    ctx.logger.info('====getAllResources==where====', where);
    const rsp = await ctx.model.TResources.findAll({ attributes: [ 'id', 'parent_id', [ 'id', 'value' ], [ 'name_cn', 'title' ], 'path', 'name', 'name_cn', 'kind', 'icon', 'hidden', 'status', 'location', 'perms', 'component', 'remark', 'sort', 'created_at' ], where, order: [[ 'sort', 'DESC' ]], raw: true });
    if (rsp) {
      return ctx.helper.body.SUCCESS({ ctx, msg: '获取成功', data: type_ === 1 ? rsp : ctx.helper.arrayToTree(rsp) });
    }
  }

  /**
   * @description: 获取资源树
   * @param {*} payload
   * @return {*}
   */
  async getTreeResources(payload) {
    const { ctx } = this;
    const { kindIds } = payload;
    const kinds = kindIds ? kindIds.split(',') : [];
    const rsp = await ctx.model.TResources.findAll({ attributes: [ 'id', [ 'name_cn', 'title' ], 'kind', 'parent_id', [ 'id', 'key' ]], where: { status: 1, hidden: 0, kind: { [Op.or]: kinds } }, order: [[ 'sort', 'DESC' ]], raw: true });
    if (rsp) {
      return ctx.helper.body.SUCCESS({ ctx, msg: '获取成功', data: { resourceTree: ctx.helper.arrayToTree(rsp), resourceIdList: ctx.helper.getArrayProps(rsp, 'id') } });
    }
  }

  async getRouters() {
    const { ctx } = this;
    const uid = ctx.helper.getUserIdByHeader(ctx);
    ctx.logger.info('==========获取菜单uid========', uid);
    // 获取用户角色
    const roles = await ctx.model.TRolesUsers.findAll({ attributes: [ 'role_id' ], where: { user_id: uid }, raw: true });
    const roleIdList = ctx.helper.getArrayProps(roles, 'role_id');
    if (roleIdList.length === 0) {
      return ctx.helper.body.ERROR({ ctx, msg: '请先配置用户角色' });
    }
    // 获取所有菜单
    const allMenus = await ctx.model.TResources.findAll({ attributes: [ 'id', [ 'name_cn', 'name' ], 'path', 'access', 'component', 'parent_id' ], where: { kind: { [Op.or]: [ 1, 4 ] }, status: 1 }, order: [[ 'sort', 'DESC' ]], raw: true });
    // 根据角色获取菜单id列表
    const roleResources = await ctx.model.TRolesResources.findAll({ where: { role_id: { [Op.in]: roleIdList } }, raw: true });
    const resourcesIdList = ctx.helper.getArrayProps(roleResources, 'resource_id');
    if (resourcesIdList.length === 0) {
      return ctx.helper.body.ERROR({ ctx, msg: '用户角色未配置菜单' });
    }
    // 根据菜单id获取菜单list
    const menus = await ctx.model.TResources.findAll({ attributes: [ 'id', [ 'name_cn', 'name' ], 'path', 'access', 'component', 'parent_id', 'icon' ], where: { id: { [Op.or]: resourcesIdList }, kind: { [Op.or]: [ 1, 4 ] }, status: 1 }, order: [[ 'sort', 'DESC' ]], raw: true });
    // 根据权限id获取权限list
    const perms = await ctx.model.TResources.findAll({ attributes: [ 'id', 'perms' ], where: { id: { [Op.or]: resourcesIdList }, kind: 5, status: 1 }, raw: true });
    // 菜单list去重
    const newMenus = ctx.helper.arrDeWeight(menus);
    // 权限list去重
    const newPerms = ctx.helper.arrDeWeight(perms);
    // 全部菜单
    const allList = ctx.helper.arrayToTree(allMenus, 'routes');
    const list = [];
    allList.forEach(item => {
      if (item.parent_id === '0' && item.routes) {
        delete item.component;
      }
      list.push(item);
    });
    // 我的菜单
    const myList = ctx.helper.arrayToTree(newMenus, 'routes');
    const myMenuList = [];
    myList.forEach(item => {
      if (item.parent_id === '0' && item.routes) {
        delete item.component;
      }
      myMenuList.push(item);
    });
    // 菜单权限
    const hasRoute = ctx.helper.getArrayProps(newMenus, 'id');
    // 按钮权限
    const permsList = ctx.helper.getArrayProps(newPerms, 'perms');
    return ctx.helper.body.SUCCESS({ ctx, msg: '获取成功', data: { allMenuList: list, menuList: myMenuList, hasRoute, permsList } });
  }
}
module.exports = ResourcesService;
